package com.biblioteca.view;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Date;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;

import org.h2.jdbcx.JdbcDataSource;

import com.biblioteca.model.entities.Emprestimo;
import com.biblioteca.model.entities.Obra;
import com.biblioteca.model.entities.Pessoa;
import com.biblioteca.model.entities.Reserva;
import com.biblioteca.model.entities.Usuario;
import com.biblioteca.model.tableModels.EmprestimoTableModel;
import com.biblioteca.model.tableModels.ObraTableModel;
import com.biblioteca.model.tableModels.PessoaTableModel;
import com.biblioteca.model.tableModels.ReservaTableModel;



@SuppressWarnings("serial")
public class FramePrincipal extends JFrame {
	
	private JTabbedPane tabbedPane ;
	private JPanel acervoPane ;
	private JPanel emprestimosPane ;
	private JPanel usuariosPane ;
	private JPanel clientesPane ;
	private JScrollPane scrollPaneAcervo ;
	private JScrollPane scrollPaneCliente;
	private JScrollPane scrollPaneEmprest;
	private JScrollPane scrollPaneReserva;
	public ObraTableModel obraModel ;
	public PessoaTableModel clienteModel;
	public EmprestimoTableModel emprestimoModel;
	public ReservaTableModel reservaModel ;
	
	
	private Dimension dimensaoTela ;
	private Usuario usuarioAtual ;
	
	private FramePrincipal frameRef = this ;
	private final int largura = 800 ;
	private final int altura = 600 ;
	private JTable obraTable;
	private JTable clienteTable;
	private JTable emprestimoTable ;
	private JTable reservaTable ;
	
	private JdbcDataSource ds ;
	public Connection conn ;
	private Statement st ;
	private ResultSet rs ;
	private PreparedStatement pst ;
	private JPanel reservasPane;

	
	public FramePrincipal() {
		
		//inicializa frame
		setTitle("GabrielMorenoFrota62961");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		checaDB() ;		
		
		setSize(largura, altura);
		setResizable(false) ;
		dimensaoTela = Toolkit.getDefaultToolkit().getScreenSize();
		setLocation(dimensaoTela.width/2-largura/2, dimensaoTela.height/2-altura/2);
		tabbedPane = new JTabbedPane();
		getContentPane().add(tabbedPane) ;
		
		//incializa painel obras
		acervoPane = new JPanel();
		tabbedPane.addTab("Catalogo de obras", null, acervoPane);
		acervoPane.setLayout(null);
		
		JButton novaObraButton = new JButton("Inserir obra");
		novaObraButton.setBounds(628, 37, 121, 23);
		acervoPane.add(novaObraButton);
		
		JButton alterarObraButton = new JButton("Alterar obra");
		alterarObraButton.setBounds(628, 96, 121, 23);
		acervoPane.add(alterarObraButton);
		
		JButton deletarObraButton = new JButton("Deletar obra");
		deletarObraButton.setBounds(628, 156, 121, 23);
		acervoPane.add(deletarObraButton);
		
		scrollPaneAcervo = new JScrollPane();
		scrollPaneAcervo.setBounds(23, 22, 569, 497);
		acervoPane.add(scrollPaneAcervo);
		
		//inicializa tabela obras
		obraModel = new ObraTableModel(this) ;
		obraTable = new JTable(obraModel);
		scrollPaneAcervo.setViewportView(obraTable);
		
		//listener de buscas em obras
		obraTable.addMouseListener(new MouseAdapter() {
			public void mouseClicked (MouseEvent e) {
				if (SwingUtilities.isRightMouseButton(e)) {
					String param = "";
					param = JOptionPane.showInputDialog(frameRef,"Realizar busca") ; 
					if (param != null) {
						obraModel.obras = new ArrayList<Obra>() ;
						int i = 0;
						boolean busca = false ;
						try {
							int id = Integer.parseInt(param); // tenta transformar a string em int, se der erro vai pro catch buscar por nome	
							while ((i<obraModel.obrasAux.size()) && (!busca) ) { //para o loop quando acha a primeira ocorrencia, pq ID � unico
								if (obraModel.obrasAux.get(i).getId() == id) {
									obraModel.obras.add(obraModel.obrasAux.get(i));
									busca = true ;
								}
								i++ ;
							}
						} catch (Exception ex) {
							while (i<obraModel.obrasAux.size()) { //procura em todo array pq titulo pode nao ser unico
								if (obraModel.obrasAux.get(i).getTitulo().equals(param)) {
									obraModel.obras.add(obraModel.obrasAux.get(i));
									busca = true ;
								}
								i++ ;
							}
						}
					if (!busca) obraModel.obras = obraModel.obrasAux ; //checa se a busca achou algo antes de mudar a tabela
					else obraModel.fireTableDataChanged();
					}
				} else if (SwingUtilities.isMiddleMouseButton(e)) {
					obraModel.obras = obraModel.obrasAux ;
					obraModel.fireTableDataChanged();
				}
			}
		});
		
		//listener no painel para limpar selecao de linha em obras
		scrollPaneAcervo.addMouseListener(new MouseAdapter(){
			public void mouseClicked(MouseEvent e) {
				if (SwingUtilities.isLeftMouseButton(e)) {
					obraTable.getSelectionModel().clearSelection();
				}
			}
		});
		
		
		
		
		//inicializa painel clientes
				clientesPane = new JPanel();
				tabbedPane.addTab("Cadastro clientes", null, clientesPane, null) ;
				clientesPane.setLayout(null);
				
				scrollPaneCliente = new JScrollPane();
				scrollPaneCliente.setBounds(23, 22, 569, 497);
				clientesPane.add(scrollPaneCliente);
						
				JButton adicionaClienteButton = new JButton("Adiciona");
				adicionaClienteButton.setBounds(628, 37, 121, 23);
				clientesPane.add(adicionaClienteButton);
				
				JButton alteraClienteButton  = new JButton("Altera");
				alteraClienteButton.setBounds(628, 96, 121, 23);
				clientesPane.add(alteraClienteButton);
				
				JButton removeClienteButton = new JButton("Remove");
				removeClienteButton.setBounds(628, 156, 121, 23);
				clientesPane.add(removeClienteButton);
				
				JButton quitaDebitoButton = new JButton("Quitar d�bitos");
				quitaDebitoButton.setBounds(628,216,121,23);
				clientesPane.add(quitaDebitoButton);
				
				//inicializa tabela cliente
				clienteModel = new PessoaTableModel(this) ;
				clienteTable = new JTable(clienteModel);
				scrollPaneCliente.setViewportView(clienteTable);
				
				//listener no painel para limpar selecao de linha em clientes
				scrollPaneCliente.addMouseListener(new MouseAdapter(){
					public void mouseClicked(MouseEvent e) {
						if (SwingUtilities.isLeftMouseButton(e)) {
							clienteTable.getSelectionModel().clearSelection();
						}
					}
				});
				
				//busca na table cliente
				clienteTable.addMouseListener(new MouseAdapter(){ //mesma logica da busca em obras
					public void mouseClicked(MouseEvent e) {
						if (SwingUtilities.isRightMouseButton(e)) {
							String param = "";
							param = JOptionPane.showInputDialog(frameRef,"Realizar busca");
							if (param != null) {
								clienteModel.clientes = new ArrayList<Pessoa>() ;
								int i = 0 ;
								boolean busca = false ;
								try {
									int id = Integer.parseInt(param);
									while ((i<clienteModel.clientesAux.size()) && (!busca) ) {
										if (clienteModel.clientesAux.get(i).getId() == id) {
											clienteModel.clientes.add(clienteModel.clientesAux.get(i));
											busca = true ;
										}
										i++ ;
									}
								} catch (Exception ex){
									while (i<clienteModel.clientesAux.size()) {
										if (clienteModel.clientesAux.get(i).getNome().equals(param)) {
											clienteModel.clientes.add(clienteModel.clientesAux.get(i));
											busca = true ;
										}
										i++ ;
									}
								}
							if (!busca) clienteModel.clientes = clienteModel.clientesAux;
							else clienteModel.fireTableDataChanged();
							}
						} else if (SwingUtilities.isMiddleMouseButton(e)) {
							clienteModel.clientes = clienteModel.clientesAux ;
							clienteModel.fireTableDataChanged();
						}
					}
				});
		
		
		//inicializa painel emprestimos
		emprestimosPane = new JPanel();
		tabbedPane.addTab("Emprestimos", null, emprestimosPane, null) ;
		emprestimosPane.setLayout(null);
		
		scrollPaneEmprest = new JScrollPane() ;
		scrollPaneEmprest.setBounds(23, 22, 569, 497);
		emprestimosPane.add(scrollPaneEmprest);
		
		JButton emprestimoButton = new JButton("Emprestar");
		emprestimoButton.setBounds(628, 37, 121, 23);
		emprestimosPane.add(emprestimoButton);
		
		JButton finalizaEmprestimoButton = new JButton("Finaliza");
		finalizaEmprestimoButton.setBounds(628, 96, 121, 23);
		emprestimosPane.add(finalizaEmprestimoButton);
				
		//inicializa tabela emprestimos
		emprestimoModel = new EmprestimoTableModel(this);
		emprestimoTable = new JTable(emprestimoModel) ;
		emprestimoTable.setRowSelectionAllowed(false);
		scrollPaneEmprest.setViewportView(emprestimoTable);
				
		//inicializa busca em emprestimos
		emprestimoTable.addMouseListener(new MouseAdapter(){
			public void mouseClicked(MouseEvent e) {
				if (SwingUtilities.isRightMouseButton(e)) {
					int linhaCliente,linhaObra,idCliente,idObra ;
					linhaCliente = clienteTable.getSelectedRow();
					linhaObra = obraTable.getSelectedRow() ;
					int i = 0 ;
					boolean busca = false ;
					if ((linhaCliente == -1) && (linhaObra == -1)) {
						JOptionPane.showMessageDialog(frameRef,"Selecione parametros para a busca");
					} else {  // entrou aqui � pq existe algum parametro, entao busca vai acontecer
						emprestimoModel.emprestimos = new ArrayList<Emprestimo>();			
						if (linhaCliente > -1) {
							if (linhaObra > -1) { // entrou aqui � busca de cliente+obra						
								idCliente = clienteModel.clientes.get(linhaCliente).getId();
								idObra = obraModel.obras.get(linhaObra).getId();
								while (i<emprestimoModel.emprestimosAux.size()) {
									if ( (emprestimoModel.emprestimosAux.get(i).getIdCliente()==idCliente) && (emprestimoModel.emprestimosAux.get(i).getIdObra()==idObra) ){
										emprestimoModel.emprestimos.add(emprestimoModel.emprestimosAux.get(i));
										busca = true ;
									}
									i++;
								}
							} else {  //entrou aqui � busca de cliente apenas
								idCliente = clienteModel.clientes.get(linhaCliente).getId();
								while (i<emprestimoModel.emprestimosAux.size()) {
									if (emprestimoModel.emprestimosAux.get(i).getIdCliente()==idCliente) {
										emprestimoModel.emprestimos.add(emprestimoModel.emprestimosAux.get(i));
										busca = true ;
									}
									i++;
								}
							}
						} else { // entrou aqui � busca de obra apenas
							idObra = obraModel.obras.get(linhaObra).getId();
							while (i<emprestimoModel.emprestimosAux.size()) {
								if (emprestimoModel.emprestimosAux.get(i).getIdObra()==idObra) {
									emprestimoModel.emprestimos.add(emprestimoModel.emprestimosAux.get(i));
									busca = true ;
								}
								i++;
							}
						}
						if (!busca) emprestimoModel.emprestimos = emprestimoModel.emprestimosAux ; //checa se a busca achou algo para alterar a visao da tabela
						else emprestimoModel.fireTableDataChanged();
					}		
				} else if (SwingUtilities.isMiddleMouseButton(e)) {
					emprestimoModel.emprestimos = emprestimoModel.emprestimosAux ;
					emprestimoModel.fireTableDataChanged();
				}
			}
		});
		
		
		
		//inicializa painel reservas
		reservasPane = new JPanel();
		tabbedPane.addTab("Reservas", null, reservasPane, null);
		reservasPane.setLayout(null);
		
		scrollPaneReserva = new JScrollPane() ;
		scrollPaneReserva.setBounds(23, 22, 569, 497);
		reservasPane.add(scrollPaneReserva);
				
		JButton reservaButton = new JButton("Reservar");
		reservaButton.setBounds(628, 37, 121, 23);
		reservasPane.add(reservaButton);
		
		JButton cancelaReservaButton = new JButton("Cancela");
		cancelaReservaButton.setBounds(628, 96, 121, 23);
		reservasPane.add(cancelaReservaButton);
				
		//inicializa tabela reservas
		reservaModel = new ReservaTableModel(frameRef);
		reservaTable = new JTable(reservaModel);
		reservaTable.setRowSelectionAllowed(false);
		scrollPaneReserva.setViewportView(reservaTable);
		
		//busca na tabela reservas
		reservaTable.addMouseListener(new MouseAdapter(){
			public void mouseClicked(MouseEvent e) {
				if (SwingUtilities.isRightMouseButton(e)) {
					int linhaCliente,linhaObra,idCliente,idObra ;
					linhaCliente = clienteTable.getSelectedRow();
					linhaObra = obraTable.getSelectedRow() ;
					int i = 0 ;
					boolean busca = false ;
					if ((linhaCliente == -1) && (linhaObra == -1)) {
						JOptionPane.showMessageDialog(frameRef,"Selecione parametros para a busca");
					} else {  // entrou aqui � pq existe algum parametro, entao busca vai acontecer
						reservaModel.reservas = new ArrayList<Reserva>();			
						if (linhaCliente > -1) {
							if (linhaObra > -1) { // entrou aqui � busca de cliente+obra						
								idCliente = clienteModel.clientes.get(linhaCliente).getId();
								idObra = obraModel.obras.get(linhaObra).getId();
								while (i<reservaModel.reservasAux.size()) {
									if ( (reservaModel.reservasAux.get(i).getIdCliente()==idCliente) && (reservaModel.reservasAux.get(i).getIdObra()==idObra) ){
										reservaModel.reservas.add(reservaModel.reservasAux.get(i));
										busca = true ;
									}
									i++;
								}
							} else {  //entrou aqui � busca de cliente apenas
								idCliente = clienteModel.clientes.get(linhaCliente).getId();
								while (i<reservaModel.reservasAux.size()) {
									if (reservaModel.reservasAux.get(i).getIdCliente()==idCliente) {
										reservaModel.reservas.add(reservaModel.reservasAux.get(i));
										busca = true ;
									}
									i++;
								}
							}
						} else { // entrou aqui � busca de obra apenas
							idObra = obraModel.obras.get(linhaObra).getId();
							while (i<reservaModel.reservasAux.size()) {
								if (reservaModel.reservasAux.get(i).getIdObra()==idObra) {
									reservaModel.reservas.add(reservaModel.reservasAux.get(i));
									busca = true ;
								}
								i++;
							}
						}
						if (!busca) reservaModel.reservas = reservaModel.reservasAux ; //checa se a busca achou algo para alterar a visao da tabela
						else reservaModel.fireTableDataChanged();
					}		
				} else if (SwingUtilities.isMiddleMouseButton(e)) {
					reservaModel.reservas = reservaModel.reservasAux ;
					reservaModel.fireTableDataChanged();
				}
			}
		});
				
		
		
		//inicializa painel usuarios do sistema
		usuariosPane = new JPanel() ;
		tabbedPane.addTab("Usuarios do sistema", null, usuariosPane, null);
		
		
		
		// inicializa listeners nos botoes
		
		// insere novas obras no catalogo
		novaObraButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				obraModel.obras = obraModel.obrasAux ;
				new FrameAdicionaObra(frameRef);
			}
		});

		//altera obras no catalogo
		alterarObraButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				int linha = obraTable.getSelectedRow();
				if (linha > -1) {
					new FrameAlteraObra(frameRef, obraModel.obras.get(linha));
				} else JOptionPane.showMessageDialog(frameRef, "Selecione uma obra para alterar");
			}
		});
		
		//deleta obra selecionada
		deletarObraButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				int linha = obraTable.getSelectedRow();
				if (linha > -1) {
					Obra o = obraModel.obras.get(linha);
					try {
						pst = conn.prepareStatement("SELECT * FROM Emprestimo WHERE obra = ?");
						pst.setInt(1, o.getId());
						rs = pst.executeQuery();
						if (!rs.next()) {
							pst = conn.prepareStatement("DELETE FROM Obra WHERE id = ?");
							pst.setInt(1,o.getId());
							pst.execute();
							obraModel.obrasAux.remove(o);
							obraModel.obras = obraModel.obrasAux ;
							obraModel.fireTableDataChanged();
							pst.close();
						} else {
							JOptionPane.showMessageDialog(frameRef,"Obra com exemplar(es) emprestado(s), impossivel deletar") ;
							pst.close();
						}
					} catch (Exception ex){
						ex.printStackTrace() ;
					}
				} else JOptionPane.showMessageDialog(frameRef, "Selecione uma obra para deletar");
			}
		});
		
		//cria novo emprestimo, caso todos os requerimentos estejam de acordo
		emprestimoButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				emprestimoModel.emprestimos = emprestimoModel.emprestimosAux ;
				int linhaObra = obraTable.getSelectedRow();
				int linhaCliente = clienteTable.getSelectedRow();
				if ((linhaObra > -1) && (linhaCliente > -1)) {
					Obra o = obraModel.obras.get(linhaObra) ;
					Pessoa c = clienteModel.clientes.get(linhaCliente);
					if (o.getQtdTotal() - o.getQtdEmp() > 0) {
						if ((c.getEmps() < 2) && (c.getDeb() == 0)) {
							if (c.getEmps() > 0) { //entrou aqui � obra disponivel e cliente com emprestimos,
								try { 			   //vai checar se cliente tem emprestimos atrasados
									pst = conn.prepareStatement("SELECT term FROM Emprestimo WHERE cliente = ?") ;
									pst.setInt(1,c.getId()) ;
									rs = pst.executeQuery() ;
									boolean irregular = false ;
									while (rs.next()) if (rs.getDate(1).compareTo(new java.util.Date()) < 0) irregular = true ;
									pst.close();	
									if (!irregular) { //entrou aqui � cliente com emprestimos sem atraso, cria emprestimo entao
										pst = conn.prepareStatement("INSERT INTO Emprestimo VALUES (?,?,CURRENT_DATE(),DATEADD('day',7,CURRENT_DATE()));") ;
										pst.setInt(1, o.getId());
										pst.setInt(2, c.getId());
										pst.execute();
										pst = conn.prepareStatement("UPDATE Cliente SET empAt = empAt+1 WHERE ID = ?") ;
										pst.setInt(1,c.getId());
										pst.execute();
										pst = conn.prepareStatement("UPDATE Obra SET qtd_emp = qtd_emp+1 , num_emp = num_emp+1 WHERE ID = ?");
										pst.setInt(1,o.getId()) ;
										pst.execute();
										o.setQtdEmp(o.getQtdEmp()+1);
										c.setEmps(c.getEmps()+1);
										pst = conn.prepareStatement("SELECT * FROM Emprestimo WHERE obra = ? AND cliente = ?");
										pst.setInt(1, o.getId());
										pst.setInt(2, c.getId());
										rs = pst.executeQuery();
										if (rs.next()) emprestimoModel.emprestimos.add(new Emprestimo (rs.getInt(1), rs.getInt(2), rs.getDate(3), rs.getDate(4)) );
										emprestimoModel.fireTableRowsInserted(emprestimoModel.emprestimos.size()-1, emprestimoModel.emprestimos.size()-1);
										pst.close();										
									} else JOptionPane.showMessageDialog(frameRef, "Cliente em situa�ao irregular, emprestimo(s) atrasado(s)");
								} catch (Exception ex) {
									JOptionPane.showMessageDialog(frameRef,"Emprestimo ja existente no banco");
									ex.printStackTrace();
								}								
							} else {  //entrou aqui � obra disponivel e cliente sem emprestimos, entao cria emprestimo direto
								try {
									pst = conn.prepareStatement("INSERT INTO Emprestimo VALUES (?,?,CURRENT_DATE(),DATEADD('day',7,CURRENT_DATE()));") ;
									pst.setInt(1, o.getId());
									pst.setInt(2, c.getId());
									pst.execute();
									pst = conn.prepareStatement("UPDATE Cliente SET empAt = empAt+1 WHERE ID = ?") ;
									pst.setInt(1,c.getId());
									pst.execute();
									pst = conn.prepareStatement("UPDATE Obra SET qtd_emp = qtd_emp+1 , num_emp = num_emp+1 WHERE ID = ?");
									pst.setInt(1,o.getId()) ;
									pst.execute();
									o.setQtdEmp(o.getQtdEmp()+1);
									c.setEmps(c.getEmps()+1);
									pst = conn.prepareStatement("SELECT * FROM Emprestimo WHERE obra = ? AND cliente = ?");
									pst.setInt(1, o.getId());
									pst.setInt(2, c.getId());
									rs = pst.executeQuery();
									if (rs.next()) emprestimoModel.emprestimos.add(new Emprestimo (rs.getInt(1), rs.getInt(2), rs.getDate(3), rs.getDate(4)) );
									emprestimoModel.fireTableRowsInserted(emprestimoModel.emprestimos.size()-1, emprestimoModel.emprestimos.size()-1);
									pst.close();
								} catch (Exception ex) {
									JOptionPane.showMessageDialog(frameRef,"Emprestimo ja existente no banco");
									ex.printStackTrace();
								}
							}
						} else JOptionPane.showMessageDialog(frameRef, "Emprestimo impossivel, cliente com d�bitos ou com o m�x de emprestimos possiveis") ;
					} else {    //entrou aqui � obra indisponivel, checa por reservas. caso existam, checa se a reserva
						try {	//com menor id � a do cliente em questao
							pst = conn.prepareStatement("SELECT COUNT(*) FROM Emprestimo WHERE obra = ?");
							pst.setInt(1, o.getId());
							rs = pst.executeQuery() ;
							rs.next();
							if (rs.getInt(1) < o.getQtdTotal()) {
								pst = conn.prepareStatement("DELETE FROM Reserva WHERE term < CURRENT_DATE()");
								pst.execute();
								pst = conn.prepareStatement("SELECT cliente FROM Reserva WHERE id = (SELECT MIN(id) FROM ((SELECT id FROM Reserva WHERE obra = ?)))");
								pst.setInt(1, o.getId());
								rs = pst.executeQuery();
								if (rs.next()) {
									if (rs.getInt(1) == c.getId()) {
										pst = conn.prepareStatement("INSERT INTO Emprestimo VALUES (?,?,CURRENT_DATE(),DATEADD('day',7,CURRENT_DATE()));") ;
										pst.setInt(1, o.getId());
										pst.setInt(2, c.getId());
										pst.execute();
										pst = conn.prepareStatement("SELECT * FROM Emprestimo WHERE obra = ? AND cliente = ?");
										pst.setInt(1, o.getId());
										pst.setInt(2, c.getId());
										rs = pst.executeQuery();
										if (rs.next()) emprestimoModel.emprestimos.add(new Emprestimo (rs.getInt(1), rs.getInt(2), rs.getDate(3), rs.getDate(4)) );
										emprestimoModel.fireTableRowsInserted(emprestimoModel.emprestimos.size()-1, emprestimoModel.emprestimos.size()-1);
										pst = conn.prepareStatement("DELETE FROM Reserva WHERE obra = ? AND cliente = ?");
										pst.setInt(1, o.getId());
										pst.setInt(2, c.getId());
										pst.execute();
										int i = 0 ;
										boolean achou = false ;
										reservaModel.reservas = reservaModel.reservasAux ;
										while ((i<reservaModel.reservas.size()) && (!achou)){
											if (reservaModel.reservas.get(i).getIdCliente() == c.getId()) {
												if (reservaModel.reservas.get(i).getIdObra() == o.getId()) {
													reservaModel.reservas.remove(i);
													achou = true ;
												}
											}
											i++;
										}
										reservaModel.fireTableDataChanged();
										pst.close();			
									} else JOptionPane.showMessageDialog(frameRef, "Obra indisponivel, todos exemplares estao emprestados/reservados") ;
								} else JOptionPane.showMessageDialog(frameRef, "Obra indisponivel, todos exemplares estao emprestados/reservados") ;
							} else JOptionPane.showMessageDialog(frameRef,"Obra indisponivel, todos exemplares estao emprestados/reservados");
						} catch (Exception ex) {
							ex.printStackTrace();
						}		
					}
				} else JOptionPane.showMessageDialog(frameRef, "Selecione um cliente e uma obra nas tabelas para realizar emprestimo") ;
			}
		});
			
		//finaliza emprestimo
		finalizaEmprestimoButton.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				int linhaObra = obraTable.getSelectedRow() ;
				int linhaCliente = clienteTable.getSelectedRow();
				if ((linhaObra > -1) && (linhaCliente > -1)) {
					try {
						Obra o = obraModel.obras.get(linhaObra);
						Pessoa c = clienteModel.clientes.get(linhaCliente);
						pst = conn.prepareStatement("UPDATE Cliente SET empAt = empAt-1 WHERE id = ?");
						pst.setInt(1,c.getId());
						pst.execute();
						pst = conn.prepareStatement("UPDATE Obra SET qtd_emp = qtd_emp-1 WHERE id = ?");
						pst.setInt(1, o.getId());
						pst.execute();
						c.setEmps(c.getEmps()-1);
						o.setQtdEmp(o.getQtdEmp()-1);
						pst = conn.prepareStatement("DELETE FROM Emprestimo WHERE obra = ? AND cliente = ?");
						pst.setInt(1, o.getId());
						pst.setInt(2, c.getId());
						pst.execute();
						int i = 0;
						boolean achou = false ;
						Date term = new java.util.Date() ;
						while ((i<emprestimoModel.emprestimosAux.size()) && (!achou)) {
							if (emprestimoModel.emprestimosAux.get(i).getIdCliente() == c.getId()){
								if (emprestimoModel.emprestimosAux.get(i).getIdObra() == o.getId()){
									term = emprestimoModel.emprestimosAux.get(i).getTerm();
									emprestimoModel.emprestimosAux.remove(i);
									achou = true ;									
								}
							}
							i++;
						}
						emprestimoModel.emprestimos = emprestimoModel.emprestimosAux ;
						emprestimoModel.fireTableDataChanged();
						if (term.compareTo(new java.util.Date()) < 0) {
							long d = term.getTime();
							long d2 = new java.util.Date().getTime() ;
							int dias ;
							d = d / (1000 * 60 * 60 * 24) ;
							d2 = d2 / (1000 * 60 * 60 * 24);							
							dias = (int)(d2-d) ;
							JOptionPane.showMessageDialog(frameRef, "Devolu�ao atrasada em "+dias+" dias, multa criada para o cliente");
							c.setDeb(c.getDeb() + (dias*2));
							pst = conn.prepareStatement("UPDATE Cliente SET deb = deb+? WHERE id = ?");
							pst.setInt(1, c.getDeb());
							pst.setInt(2, c.getId());
							pst.execute();
							pst.close();
						}
					} catch(Exception ex) {
						ex.printStackTrace();
					}	
				} else JOptionPane.showMessageDialog(frameRef, "Selecione uma obra e um cliente para finalizar emprestimo");
			}
		});
		
		//cria nova reserva
		reservaButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				reservaModel.reservas = reservaModel.reservasAux ;
				int linhaObra = obraTable.getSelectedRow();
				int linhaCliente = clienteTable.getSelectedRow();
				if ((linhaObra > -1) && (linhaCliente > -1)) {
					Obra o = obraModel.obras.get(linhaObra) ;
					Pessoa c = clienteModel.clientes.get(linhaCliente);
					if (o.getQtdTotal() <= o.getQtdEmp()) {
						if (c.getEmps() < 2) {
							if (c.getEmps() > 0) {
								try {
									pst = conn.prepareStatement("SELECT term FROM Emprestimo WHERE cliente = ?") ;
									pst.setInt(1,c.getId()) ;
									rs = pst.executeQuery() ;
									boolean irregular = false ;
									while (rs.next()) if (rs.getDate(1).compareTo(new java.util.Date()) < 0) irregular = true ;
									pst.close();	
									if (!irregular) {
										pst = conn.prepareStatement("SELECT * FROM Emprestimo WHERE obra = ? AND cliente = ?");
										pst.setInt(1,o.getId());
										pst.setInt(2,c.getId());
										rs = pst.executeQuery();
										if (!rs.next()) {
											pst = conn.prepareStatement("INSERT INTO Reserva VALUES (null,?,?,CURRENT_DATE(),DATEADD('day',2,CURRENT_DATE()));") ;
											pst.setInt(1, o.getId());
											pst.setInt(2, c.getId());
											pst.execute();
											pst = conn.prepareStatement("UPDATE Cliente SET empAt = empAt+1 WHERE ID = ?") ;
											pst.setInt(1,c.getId());
											pst.execute();
											pst = conn.prepareStatement("UPDATE Obra SET qtd_emp = qtd_emp+1 , num_emp = num_emp+1 WHERE ID = ?");
											pst.setInt(1,o.getId()) ;
											pst.execute();
											o.setQtdEmp(o.getQtdEmp()+1);
											c.setEmps(c.getEmps()+1);
											pst = conn.prepareStatement("SELECT * FROM Reserva WHERE obra = ? AND cliente = ?");
											pst.setInt(1, o.getId());
											pst.setInt(2, c.getId());
											rs = pst.executeQuery();
											if (rs.next()) reservaModel.reservas.add(new Reserva (rs.getInt(2), rs.getInt(3), rs.getDate(4), rs.getDate(5)) );
											reservaModel.fireTableRowsInserted(reservaModel.reservas.size()-1, reservaModel.reservas.size()-1);
											pst.close();
										} else JOptionPane.showMessageDialog(frameRef,"Reserva impossivel, ja existe um emprestimo da mesma obra para o mesmo cliente");										
									} else JOptionPane.showMessageDialog(frameRef, "Cliente em situa�ao irregular, emprestimo(s) atrasado(s)");
								} catch (Exception ex) {
									JOptionPane.showMessageDialog(frameRef,"Reserva ja existente no banco");
									ex.printStackTrace();
								}								
							} else {
								try {
									pst = conn.prepareStatement("INSERT INTO Reserva VALUES (null,?,?,CURRENT_DATE(),DATEADD('day',2,CURRENT_DATE()));") ;
									pst.setInt(1, o.getId());
									pst.setInt(2, c.getId());
									pst.execute();
									pst = conn.prepareStatement("UPDATE Cliente SET empAt = empAt+1 WHERE ID = ?") ;
									pst.setInt(1,c.getId());
									pst.execute();
									pst = conn.prepareStatement("UPDATE Obra SET qtd_emp = qtd_emp+1 , num_emp = num_emp+1 WHERE ID = ?");
									pst.setInt(1,o.getId()) ;
									pst.execute();
									o.setQtdEmp(o.getQtdEmp()+1);
									c.setEmps(c.getEmps()+1);
									pst = conn.prepareStatement("SELECT * FROM Reserva WHERE obra = ? AND cliente = ?");
									pst.setInt(1, o.getId());
									pst.setInt(2, c.getId());
									rs = pst.executeQuery();
									if (rs.next()) reservaModel.reservas.add(new Reserva (rs.getInt(2), rs.getInt(3), rs.getDate(4), rs.getDate(5)) );
									reservaModel.fireTableRowsInserted(reservaModel.reservas.size()-1, reservaModel.reservas.size()-1);
									pst.close();
								} catch (Exception ex) {
									JOptionPane.showMessageDialog(frameRef,"Reserva ja existente no banco");
									ex.printStackTrace();
								}
							}
						} else JOptionPane.showMessageDialog(frameRef, "Cliente no limite m�ximo de emprestimos simultaneos (2)") ;
					} else JOptionPane.showMessageDialog(frameRef, "Reserva impossivel, existem exemplares disponiveis") ;
				} else JOptionPane.showMessageDialog(frameRef, "Selecione um cliente e uma obra nas tabelas para realizar reserva") ;
			}
		});
				
		//cancela reserva
		cancelaReservaButton.addActionListener(new ActionListener(){
			public void actionPerformed(ActionEvent e){
				int linhaObra = obraTable.getSelectedRow() ;
				int linhaCliente = clienteTable.getSelectedRow();
				if ((linhaObra > -1) && (linhaCliente > -1)) {
					try {
						Obra o = obraModel.obras.get(linhaObra);
						Pessoa c = clienteModel.clientes.get(linhaCliente);
						pst = conn.prepareStatement("UPDATE Cliente SET empAt = empAt-1 WHERE id = ?");
						pst.setInt(1,c.getId());
						pst.execute();
						pst = conn.prepareStatement("UPDATE Obra SET qtd_emp = qtd_emp-1 WHERE id = ?");
						pst.setInt(1, o.getId());
						pst.execute();
						c.setEmps(c.getEmps()-1);
						o.setQtdEmp(o.getQtdEmp()-1);
						pst = conn.prepareStatement("DELETE FROM Reserva WHERE obra = ? AND cliente = ?");
						pst.setInt(1, o.getId());
						pst.setInt(2, c.getId());
						pst.execute();
						int i = 0;
						boolean achou = false ;
						while ((i<reservaModel.reservasAux.size()) && (!achou)) {
							if (reservaModel.reservasAux.get(i).getIdCliente() == c.getId()){
								if (reservaModel.reservasAux.get(i).getIdObra() == o.getId()){
									reservaModel.reservasAux.remove(i);
									achou = true ;									
								}
							}
							i++;
						}
						reservaModel.reservas = reservaModel.reservasAux ;
						reservaModel.fireTableDataChanged();
					} catch(Exception ex) {
						ex.printStackTrace();
					}	
				} else JOptionPane.showMessageDialog(frameRef, "Selecione uma obra e um cliente para cancelar reserva");
			}
		});		
		
		// insere novos clientes
		adicionaClienteButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				clienteModel.clientes = clienteModel.clientesAux ;
				new FrameAdicionaCliente(frameRef);
			}
		});
		
		// altera informa�oes cliente
		alteraClienteButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				int linha = clienteTable.getSelectedRow(); 
				if (linha > -1) {
					new FrameAlteraCliente(frameRef,clienteModel.clientes.get(linha));
				} else JOptionPane.showMessageDialog(frameRef, "Selecione um cliente para alterar");
			}
		});
				
		//deleta clientes que nao tem nenhum emprestimo ativo e nenhum d�bito
		removeClienteButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				int linha = clienteTable.getSelectedRow();
				if (linha > -1) {
					Pessoa c = clienteModel.clientes.get(linha);
					try {
						pst = conn.prepareStatement("SELECT * FROM Emprestimo WHERE cliente = ?");
						pst.setInt(1, c.getId());
						rs = pst.executeQuery();
						if (!rs.next() && (c.getDeb()==0)) {
							pst = conn.prepareStatement("DELETE FROM Cliente WHERE id = ?");
							pst.setInt(1,c.getId());
							pst.execute();
							clienteModel.clientesAux.remove(c);
							clienteModel.clientes = clienteModel.clientesAux ;
							clienteModel.fireTableRowsDeleted(linha, linha);
							pst.close();
						} else {
							JOptionPane.showMessageDialog(frameRef,"Cliente com emprestimo(s) ativo(s), impossivel remover") ;
							pst.close();
						}
					} catch (Exception ex){
						ex.printStackTrace() ;
					}
				} else JOptionPane.showMessageDialog(frameRef, "Selecione um cliente para remover");
			}
		});
		
		quitaDebitoButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e){
				int linha = clienteTable.getSelectedRow();
				if (linha > -1) {
					Pessoa c = clienteModel.clientes.get(linha);
					try {
						pst = conn.prepareStatement("UPDATE Cliente SET deb = 0 WHERE id = ?") ;
						pst.setInt(1,c.getId());
						pst.execute();
						pst.close();
						c.setDeb(0);
						clienteModel.fireTableDataChanged();
					} catch (Exception ex){
						ex.printStackTrace();
					}
				}
			}
		}) ;
		
		setVisible(true);
		
		//listener que ativa/desativa o painel restrito a administradores
		FrameLogin fl = new FrameLogin(this) ;
		fl.addWindowListener(new WindowAdapter(){
			@Override
			public void windowClosed (WindowEvent e) {
				if (usuarioAtual.getNivel() > 0) tabbedPane.setEnabledAt(4, false) ;
				else tabbedPane.setEnabledAt(4, true);
			}
		});
	}
	//fim do construtor
	
	private void checaDB() {		

		//fun�ao checa se � a primeira execu�ao do programa, e cria a base de dados caso necessario
		try {
			ds = new JdbcDataSource() ;
			ds.setURL("jdbc:h2:DB/database") ;
			conn = ds.getConnection();
			st = conn.createStatement();
			rs = st.executeQuery("SELECT COUNT(*) FROM information_schema.tables WHERE table_name = 'USUARIO'");
			rs.next();
			int i = rs.getInt(1);
			st.close();
			if (i == 0) {
				st = conn.createStatement();
				st.execute("CREATE TABLE Usuario(id INT AUTO_INCREMENT, nome VARCHAR(15), senha VARCHAR(15), nivel INT, PRIMARY KEY(nome));");
				st.execute("INSERT INTO Usuario VALUES (null,'admin','admin',0);");
				st.execute("INSERT INTO Usuario VALUES (null,'atendente','atendente',1)");
				st.execute("CREATE TABLE Obra(id INT AUTO_INCREMENT, titulo VARCHAR(30), autor VARCHAR(30), categoria VARCHAR(12), qtd_total INT, qtd_emp INT, num_emp INT, PRIMARY KEY (titulo,autor));");
				st.execute("CREATE TABLE Cliente(id INT AUTO_INCREMENT, nome VARCHAR(15), telefone INT, empAt INT, deb INT, PRIMARY KEY (id));");
				st.execute("CREATE TABLE Emprestimo(obra INT, cliente INT, inic DATE, term DATE, PRIMARY KEY (obra,cliente), FOREIGN KEY (cliente) REFERENCES Cliente(id), FOREIGN KEY (obra) REFERENCES Obra(id))");
				st.execute("CREATE TABLE Reserva(id INT AUTO_INCREMENT, obra INT, cliente INT, inic DATE, term DATE, PRIMARY KEY (obra,cliente), FOREIGN KEY (cliente) REFERENCES Cliente(id), FOREIGN KEY (obra) REFERENCES Obra(id))");
				st.execute("INSERT INTO Obra VALUES (null,'AAA', 'BBB', 'Livro', 5, 0, 0);") ;
				st.execute("INSERT INTO Obra VALUES (null,'CCC', 'DDD', 'Mapa', 4, 0, 0);") ;
				st.execute("INSERT INTO Obra VALUES (null,'FFF', 'EEE', 'Dicionario', 3, 0, 0);");
				st.execute("INSERT INTO Cliente VALUES(null,'joao',1111111,0,0)");
				st.execute("INSERT INTO Cliente VALUES(null,'maria',222222,0,8)");
				st.execute("INSERT INTO Cliente VALUES(null,'pedro',333333,0,0)");
				st.execute("INSERT INTO Reserva VALUES(null, 1, 1, DATEADD('day',-10,CURRENT_DATE()), DATEADD('day',-10,CURRENT_DATE()) )");
				st.execute("INSERT INTO Emprestimo VALUES (2,3,DATEADD('day',-10,CURRENT_DATE()),DATEADD('day',-3,CURRENT_DATE()))") ;
				st.execute("UPDATE Obra SET qtd_emp = qtd_emp+1 , num_emp = num_emp+1 WHERE id = 2");
				st.execute("UPDATE Cliente SET empAt = empAt+1 WHERE id = 3");
				st.close();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	
	}
	
	public int getLargura() {
		return largura ;
	}

	public int getAltura() {
		return altura ;
	}

	public Usuario getUsuarioAtual() {
		return usuarioAtual ;
	}

	public void setUsuarioAtual(Usuario u) {
		usuarioAtual = u ;		
	}
	
	public JTable getObraTable() {
		return obraTable ;
	}
	
	public static void main (String args[]) {
		new FramePrincipal() ;
	}
}
